package com.hhit.zhgd.config

import com.fasterxml.jackson.annotation.JsonAutoDetect
import com.fasterxml.jackson.annotation.PropertyAccessor
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator
import org.springframework.cache.annotation.EnableCaching
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.data.redis.connection.RedisConnectionFactory
import org.springframework.data.redis.core.RedisTemplate
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer
import org.springframework.data.redis.serializer.StringRedisSerializer

@Configuration
@EnableCaching
class RedisConfig {

    @Bean
    fun redisTemplate(factory: RedisConnectionFactory):RedisTemplate<String,Any?> {
        val redisTemplate = RedisTemplate<String, Any?>()

        redisTemplate.connectionFactory = factory
        val stringRedisSerializer = StringRedisSerializer()
        redisTemplate.keySerializer = stringRedisSerializer

        // 用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值
        redisTemplate.valueSerializer = serializer()
        return redisTemplate
    }

    private fun serializer(): Jackson2JsonRedisSerializer<Any?> {
        // 使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值（默认使用JDK的序列化方式）
        val jackson2JsonRedisSerializer: Jackson2JsonRedisSerializer<Any?> = Jackson2JsonRedisSerializer(Any::class.java)
        val objectMapper = ObjectMapper()
        // 指定要序列化的域，field,get和set,以及修饰符范围，ANY是都有包括private和public
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY)

        // 指定序列化输入的类型（序列化时将对象全类名一起保存下来），类必须是非final修饰的，final修饰的类会抛出异常
        // objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); 方法已过期，用activateDefaultTyping代替
        objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL)
        jackson2JsonRedisSerializer.setObjectMapper(objectMapper)
        return jackson2JsonRedisSerializer
    }
}